package com.jwpdk.dbframework;

import java.sql.Connection;
import java.sql.Timestamp;
import java.text.DateFormat;
import java.text.SimpleDateFormat;

import org.apache.log4j.Logger;

import com.jwpdk.appframework.data.DataMap;
import com.jwpdk.appframework.data.DatasetList;
import com.jwpdk.appframework.data.IData;
import com.jwpdk.appframework.data.IDataList;
import com.jwpdk.common.Config;
import com.jwpdk.util.StringUtils;

/**
 * 
 */
public class DaoManager {

	protected Logger			log					= Logger.getLogger(this.getClass());
	private IDAO				idao				= DBFactory.getInstance().getDao();
	private Connection			connection;
	private ConnectionManager	connectionManager	= ConnectionManager.getInstance();
	private TransactionManager	transactionManager	= TransactionManager.getInstance();
	private String				transactionName;
	private Transaction			transaction;

	/**
	 * @param transactionName
	 * @throws Exception
	 */
	public DaoManager(String transactionName) throws Exception {
		this.transactionName = transactionName;
	}

	/**
	 * @param transaction
	 * @throws Exception
	 */
	public DaoManager(Transaction transaction) throws Exception {
		this.transaction = transaction;
	}

	public DaoManager() throws Exception {
	}

	/**
	 * 检查事务是否开启
	 * @throws Exception
	 */
	private void checkTransation() throws Exception {
		if ( connection == null ) {
			String tranString = transactionName != null ? transactionName : (transaction != null ? transaction.getTransactionName() : transactionManager.getCurrenTransaction().getTransactionName());
			if ( connectionManager.isNotExistsConnection(tranString) || !transactionManager.geTransaction(tranString).isOpen() ) {
				throw new Exception("未开启事物管理！！");
			} else {
				connection = connectionManager.getConnection(tranString);
			}
			log.debug("使用事务：" + tranString);
		}
	}

	/**
	 * 执行查询sql
	 * @param sql
	 * @return IDataList
	 * @throws Exception
	 */
	public IDataList executeQuery(SQL sql) throws Exception {
		IStatement statement = getStatement(sql);
		IDataList idl = idao.queryByIStatement(statement);
		return idl;
	}

	/**
	 * 获取SQL执行总数
	 * @param sql
	 * @return
	 * @throws Exception
	 */
	public int getCount(SQL sql) throws Exception {
		checkTransation();
		return idao.getCount(connection,sql);
	}

	/**
	 * 执行无参SQL集合，返回所有结果集的集合。
	 * @param sql[]
	 * @return ResultSet[]
	 * @throws Exception
	 */
	@SuppressWarnings("unchecked")
	public IDataList executeQueryS(SQL[] sql) throws Exception {
		IDataList rsDataList = new DatasetList();
		IStatement statement = null;
		for (int i = 0; i < sql.length; i++) {
			statement = getStatement(sql[i]);
			rsDataList.addAll(idao.queryByIStatement(statement));
		}
		return rsDataList;
	}

	/**
	 * 执行CUD
	 * @param conn
	 * @param sql
	 * @return int
	 * @throws Exception
	 */
	public int executeUpdate(SQL sql) throws Exception {
		IStatement statement = getStatement(sql);
		int result = idao.executeByIStatement(statement);
		return result;
	}

	/**
	 * 获取数据库系统时间
	 * @param conn
	 * @return String
	 * @throws Exception
	 */
	public String getSysDate(String format) throws Exception {
		Timestamp time = getCurrentTime();
		DateFormat dfmt = new SimpleDateFormat(format);
		return dfmt.format(time);
	}

	/**
	 * 获取当前数据库系统时间的 Timestamp类型
	 * @return
	 * @throws Exception
	 */
	public Timestamp getCurrentTime() throws Exception {
		checkTransation();
		return idao.getSysdate(connection);
	}

	/**
	 * 获取SQL_MAP映射数据
	 * @param sqlref
	 * @return
	 * @throws Exception
	 */
	@SuppressWarnings("unchecked")
	public IData getSqlMapData(String sqlref) throws Exception {
		Config config = Config.getInstance();
		StringBuffer sqlBuffer = new StringBuffer();
		sqlBuffer.append("SELECT DOMAIN_NAME,SQL_REF,SQL_STMT,SQL_TYPE ");
		sqlBuffer.append(" FROM ").append(config.getSqlMapTable());
		sqlBuffer.append("	WHERE SYSDATE BETWEEN START_DATE AND END_DATE ");
		if ( !StringUtils.IsEmptyOrNull(sqlref) ) {
			sqlBuffer.append(" AND SQL_REF=:SQL_REF ");
		}
		sqlBuffer.append(" AND (:DOMAIN_NAME IS NULL OR DOMAIN_NAME = :DOMAIN_NAME )");
		sqlBuffer.append(" ORDER BY DOMAIN_NAME ,SQL_REF");

		IDataList iDataList = new DatasetList();
		try {
			// 将构造链接设置为当前链接
			String[] domains = config.getSqlMapDomain();
			SQL sqlp = new SQL();
			if ( domains != null ) {
				for (int i = 0; i < domains.length; i++) {
					sqlp.setSql(sqlBuffer.toString(),true);
					sqlp.set("DOMAIN_NAME",domains[i]);
					if ( !StringUtils.IsEmptyOrNull(sqlref) ) {
						sqlp.set("SQL_REF",sqlref);
					}
					iDataList.addAll(executeQuery(sqlp));
				}
			} else {
				sqlp.setSql(sqlBuffer.toString(),true);
				sqlp.set("DOMAIN_NAME",null);
				if ( !StringUtils.IsEmptyOrNull(sqlref) ) {
					sqlp.set("SQL_REF",sqlref);
				}
				iDataList = executeQuery(sqlp);
			}
			if ( log.isDebugEnabled() ) {
				log.debug("IDataList:" + iDataList);
			}
		} catch ( Exception e ) {
			log.error(e);
			throw e;
		}

		return getIData(iDataList);

	}

	@SuppressWarnings("unchecked")
	private IData getIData(IDataList ids) {
		IData rs = new DataMap();
		for (int i = 0; i < ids.size(); i++) {
			rs.put(ids.get(i,"SQL_REF").toString(),ids.get(i));
		}
		return rs;

	}

	/**
	 * 根据SQL对象获取IStatement
	 * @param sql
	 * @return
	 */
	private IStatement getStatement(SQL sql) throws Exception {
		checkTransation();
		IStatement iStatement = null;
		if ( sql.isParamSql() ) {
			iStatement = new ParameterStatement(connection, sql);
		} else {
			iStatement = new SimpleStatement(connection, sql);
		}
		return iStatement;
	}
}